﻿namespace CoProjectDF.Views.Login
{
    using System.ComponentModel;
    using System.ComponentModel.Composition;
    using System.Windows;
    using System.Windows.Controls;
    using CoProjectDF.Models;
    using IdeaBlade.EntityModel;
    using IdeaBlade.Application.Framework.Core.Authentication;
    using Caliburn.Micro;

    /// <summary>
    /// <see cref="UserControl"/> class that shows the current login status and allows login and logout.
    /// </summary>
    [Export]
    public partial class LoginStatus : UserControl, INotifyPropertyChanged
    {

        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Creates a new <see cref="LoginStatus"/> instance.
        /// </summary>

        public LoginStatus()
        {
            AuthenticationService = Caliburn.Micro.IoC.Get<IAuthenticationService>();

            this.InitializeComponent();
            this.DataContext = this;

            AuthenticationService.LoggedIn += (o, e) => UpdateLoginState();
            AuthenticationService.LoggedOut += (o, e) => UpdateLoginState();
            //AuthenticationManager.Current.LoggedIn += (o, e) => UpdateLoginState();
            //AuthenticationManager.Current.LoggedOut += (o, e) => UpdateLoginState();

            this.UpdateLoginState();
        }

        private IAuthenticationService _authenticationService;
        //[Import]
        public IAuthenticationService AuthenticationService
        {
            get { return _authenticationService; }
            set { _authenticationService = value; }
        }

        public string UserName
        {
            get { return IsLoggedIn ? string.Format(ApplicationStrings.WelcomeMessage, User.Name) : string.Empty; }
        }

        public bool IsLoggedIn
        {
            get { return User != null && User.IsAuthenticated; }
        }

        private UserBase User
        {
            get
            {
                if (AuthenticationService != null)
                    return (AuthenticationService.Principal as UserBase);
                else
                    return null;
            }
        }

        private void LoginButton_Click(object sender, RoutedEventArgs e)
        {
            LoginRegistrationWindow loginWindow = new LoginRegistrationWindow();
            loginWindow.Show();
        }

        private void LogoutButton_Click(object sender, RoutedEventArgs e)
        {
            if (AuthenticationService != null)
                AuthenticationService.LogoutAsync(() => { }, f => { ErrorWindow.CreateNew(f.Message.ToString()); });

            /*
            AuthenticationManager.Current.Logout(op =>
            {
                if (op.HasError)
                {
                    ErrorWindow.CreateNew(op.Error);
                    op.MarkErrorAsHandled();
                }
            });
            */
        }

        private bool IsWindowsAuthenticated
        {
            //get { return AuthenticationManager.Current.User.AuthenticationType == "NTLM"; }
            get
            {
                if (AuthenticationService != null)
                {
                    return (AuthenticationService.Principal as User).AuthenticationType == "NTLM";
                }
                else 
                    return false;
            }
        }

        private void UpdateLoginState()
        {
            if (IsLoggedIn)
            {
                //VisualStateManager.GoToState(this, IsWindowsAuthenticated ? "windowsAuth" : "loggedIn", true); 
                VisualStateManager.GoToState(this, "loggedIn", true);
            }
            else
            {
                VisualStateManager.GoToState(this, "loggedOut", true);
            }

            RaisePropertyChanged("UserName");
            RaisePropertyChanged("IsLoggedIn");
        }

        private void RaisePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}
